import axios from 'axios';
import cookies from 'cookies-js';
import { message } from 'ant-design-vue';
import { useCounterStore } from '@/stores/counter';

const HTPP_MESSAGE = {
    TOKEN_EXPIRED: '登录超时，请重新登录',
    ERROR_404: '404，抱歉页面出错了',
    ERROR_PATH: '抱歉，页面出错了',
    ERROR_NET: '网络错误，请稍后再试'
};

class Request {
    // axios实例
    axiosInstance = null;
    // axios配置
    axiosRequestConfig = {};
    // 是否已经弹出错误提示
    isErrorMsg = false;
    constructor(baseURL) {
        this.axiosRequestConfig.timeout = 60000; // 全局超时时限
        if (baseURL) {
            this.axiosRequestConfig.baseURL = baseURL;
        }
        this.axiosInstance = axios.create(this.axiosRequestConfig); // 创建axios实例
        this.axiosInstance.interceptors.request.use(this.onRequest.bind(this)); // 请求拦截
        this.axiosInstance.interceptors.response.use(this.onResponseSuccess.bind(this), this.onResponseError.bind(this)); // 响应拦截
    }

    // 处理错误信息
    messageError = (msg) => {
        if (!this.isErrorMsg) {
            this.isErrorMsg = true;
            message.error(msg || HTPP_MESSAGE.ERROR_NET);
            setTimeout(() => {
                this.isErrorMsg = false;
            }, 3000);
        }
    };

    // Token错误处理
    pastDueHandle = () => {
        // 退出登录操作，回到登录页
    };

    // 请求拦截
    onRequest(request) {
        // 始终用最新的token
        const token = cookies.get('token');
        request.headers.token = token;
        const store = useCounterStore();
        if (store) {
            // 设置请求头
            // const { groupCode, projectId, application } = store;
            // request.headers['project-id'] = projectId;
            // request.headers['group-code'] = groupCode;
            // request.headers['application'] = application;
        }
        const extraHeaders = request.extraHeaders || {};

        // 需要额外加header的接口
        if (extraHeaders && Object.keys(extraHeaders).length > 0) {
            for (const key in extraHeaders) {
                if (Object.prototype.hasOwnProperty.call(extraHeaders, key)) {
                    request.headers[key] = extraHeaders[key];
                }
            }
        }
        return request;
    }

    // 响应拦截
    onResponseSuccess(response) {
        const { status, data: res } = response;
        // 接口返回200
        const { code } = res;
        
        if (code && typeof code === 'number') {
            switch (code) {
                case 200:
                    return Promise.resolve(res.data);
                case 401:
                case 403:
                    this.messageError(HTPP_MESSAGE.TOKEN_EXPIRED);
                    this.pastDueHandle();
                    break;
                default:
                    this.messageError(res.message);
                    break;
            }
            return Promise.reject();
        }

        if ((status >= 200 && status < 300) || status === 304) {
            return res;
        }

        if (status === 401 || status === 403) {
            this.messageError(HTPP_MESSAGE.TOKEN_EXPIRED);
            this.pastDueHandle();
            return Promise.reject();
        }
        if (status === 404) {
            this.messageError(HTPP_MESSAGE.ERROR_404);
            return Promise.reject();
        }
        this.messageError(res.message || HTPP_MESSAGE.ERROR_NET);
        return Promise.reject();
    }

    // 响应错误拦截
    onResponseError(error) {
        const { response } = error;
        switch (response?.status) {
            case 403:
                this.messageError(HTPP_MESSAGE.TOKEN_EXPIRED);
                this.pastDueHandle();
                return Promise.reject(error);
            default:
                break;
        }
        // 三秒之内的多个接口错误信息，只显示一个错误信息
        this.messageError(response?.data?.message || response?.data?.error);
        return Promise.reject(error);
    }

    // get请求
    get(url, params, config) {
        return this.axiosInstance.get(url, {...config, params});
    }

    // post请求
    post(url, data, config) {
        return this.axiosInstance.post(url, data, config);
    }

    // put请求
    put(url, data, config) {
        return this.axiosInstance.put(url, data, config);
    }

    // delete请求
    delete(url, params, config) {
        return this.axiosInstance.delete(url, { ...config, params });
    }
}

export const http = new Request();
